package dynamic

import (
	"errors"
	"github.com/gin-gonic/gin"
	"strings"
	"time"
	"vrcm/src/vrcm/app/admin/models/dynamic"
	"vrcm/src/vrcm/app/consts"
	"vrcm/src/vrcm/app/do/request"
)

func (this DynamicServer) DynamicUpdateNotReqNgvsa(c *gin.Context, req request.DynamicEdit) (interface{}, error) {
	var (
		tmp = dynamic.Dynamic{}
	)
	err := this.Orm.Model(dynamic.Dynamic{}).
		Where("packageId = ?", req.PackageId).
		Find(&tmp).Error
	if err != nil {
		this.Log.Errorf("DynamicUpdate Orm Find error: %v \r\n", err)
		return nil, dbErr
	}
	if tmp.Id <= 0 {
		return nil, targetNotExist
	}
	// origin
	stuct := this.sqlToStuctSingle(tmp)
	added, _, _ := this.compareDynamicRules(stuct, req)

	var (
		newIds string
	)
	reqFormat := this.formatDomainReqData(req, tmp.Cname)

	for key, _ := range reqFormat {
		for _, v := range added {
			if v.Protocol == consts.ProtocolTCP || v.Protocol == consts.ProtocolUdp {
				newIds += (v.CnameX + domainTag + v.Protocol + v.DynamicPort + domainTag + v.RuleId + splitTag)
			} else {
				newIds += (reqFormat[key].RequestDomain + domainTag + v.Protocol + domainTag + v.RuleId + splitTag)
			}
			if tmp.Cname == "" {
				tmp.Cname = v.CnameX
			}
			//time.Sleep(time.Millisecond * 50)
		}
	}

	tx := this.Orm.Begin()
	defer tx.Rollback()
	err = tx.Model(dynamic.Dynamic{}).
		Where("packageId = ?", req.PackageId).
		Delete(&dynamic.Dynamic{}).Error
	if err != nil {
		return nil, dbErr
	}
	oldTag := dynamic.Dynamic{
		InstanceId:     tmp.InstanceId,
		InstanceName:   tmp.InstanceName,
		Id:             req.Id,
		ExpirationTime: tmp.ExpirationTime,
	}
	fields := this.convertToMySQLFields(req, newIds, tmp.Cname, oldTag, "", 0)
	fields.Id = tmp.Id
	err = tx.Model(&dynamic.Dynamic{}).Create(&fields).Error
	if err != nil {
		return nil, dbErr
	}
	tx.Commit()
	idMap := this.getIds(newIds)
	//fmt.Println(" ===> idMap ===>", idMap)
	err = this.createDILogNotReqNgvsa(req, tmp.InstanceId, idMap, tmp.Cname)
	if err != nil {
		return nil, err
	}
	return nil, nil
}

func (this DynamicServer) createDILogNotReqNgvsa(req request.DynamicEdit, uid string, idM map[string]string, cname string) error {
	if req.DynamicType == consts.DynamicIpType {
		return this.createDILogLayer4NotReqNgvsa(req, uid, idM)
	}
	dms := strings.Split(req.Domains, splitTag)
	var (
		cDta = make([]dynamic.DynamicInstance, 0)
		now  = time.Now()
	)
	for _, val := range dms {
		for _, v := range req.Rules {
			// 获取其 proxy port
			tmp := dynamic.DynamicInstance{
				InstanceId: uid,
				Domain:     val,
				CreateTime: now,
				TenantId:   req.TenantId,
				PakId:      req.PackageId,
				Protocol:   v.Protocol,
				Port:       v.DynamicPort,
				//IsSystem:   v.IsSystem,
			}
			if v.Protocol == consts.ProtocolTCP || v.Protocol == consts.ProtocolUdp {
				//proxyPort, err := this.getProxyPort(v.Protocol, v.DynamicPort)
				//if err != nil {
				//	return err
				//}
				tmp.NgvsaInstanceId = idM[v.CnameX+domainTag+v.Protocol+v.DynamicPort+domainTag]
				//tmp.ProxyPort = proxyPort
			} else {
				tmp.NgvsaInstanceId = idM[val+domainTag+v.Protocol+domainTag]
			}

			tag := dynamic.DynamicInstance{}
			err := this.Orm.Model(dynamic.DynamicInstance{}).
				Where("instanceId = ?", uid).
				Where("domain = ?", val).
				Where("port = ?", v.DynamicPort).
				Where("protocol = ?", v.Protocol).
				Where("ngvsaInstanceId = ?", tmp.NgvsaInstanceId).
				Find(&tag).
				Error
			if err != nil {
				this.Log.Errorf("createDILog error(%s): %s, log-tag-id: %d\r\n", val, err.Error(), tag.ID)
				return errors.New("create Instance Log Err")
			}
			if tag.ID > 0 {
				//if tag.IsSystem == "own" && tmp.IsSystem == "system" {
				//	err = this.Orm.Model(dynamic.DynamicInstance{}).
				//		Where("id = ?", tag.ID).
				//		Update("isSystem", "system").Error
				//}
				this.Log.Errorf("target domain already exist %s tagID: %s\r\n", val, tag.ID)
				continue
			}
			cDta = append(cDta, tmp)
			time.Sleep(time.Millisecond * 20)
		}
	}
	if len(cDta) == 0 {
		return nil
	}
	return this.Orm.Model(dynamic.DynamicInstance{}).Create(&cDta).Error
}

func (this DynamicServer) createDILogLayer4NotReqNgvsa(req request.DynamicEdit, uid string, idM map[string]string) error {
	var (
		cDta = make([]dynamic.DynamicInstance, 0)
		now  = time.Now()
	)
	for _, v := range req.Rules {
		var (
			proxyPort string
		)
		tmp := dynamic.DynamicInstance{
			InstanceId: uid,
			Domain:     "",
			CreateTime: now,
			TenantId:   req.TenantId,
			PakId:      req.PackageId,
			Protocol:   v.Protocol,
			Port:       v.DynamicPort,
			ProxyPort:  proxyPort,
			//IsSystem:   v.IsSystem,
		}
		tmp.NgvsaInstanceId = idM[v.CnameX+domainTag+v.Protocol+v.DynamicPort+domainTag]
		tag := dynamic.DynamicInstance{}
		err := this.Orm.Model(dynamic.DynamicInstance{}).
			Where("instanceId = ?", uid).
			Where("domain = ?", "").
			Where("port = ?", v.DynamicPort).
			Where("tenantId = ?", req.TenantId).
			Where("protocol = ?", v.Protocol).
			//Where("proxyPort = ?", proxyPort).
			Where("ngvsaInstanceId = ?", tmp.NgvsaInstanceId).
			Find(&tag).
			Error
		if err != nil {
			this.Log.Errorf("createDILogLayer error(%s): %s, log-tag-id: %d\r\n", "", err.Error(), tag.ID)
			return errors.New("create Instance Log Err")
		}
		if tag.ID > 0 {
			this.Log.Errorf("target domain already exist %s tagID: %s\r\n", "", tag.ID)
			continue
		}

		cDta = append(cDta, tmp)
		time.Sleep(time.Millisecond * 20)
	}
	if len(cDta) == 0 {
		return nil
	}
	return this.Orm.Model(dynamic.DynamicInstance{}).Create(&cDta).Error
}
